/*
#include <kaleidoscope/frontend/semantic_analysis/resolve.hpp>
//=====================================================================
#include <kaleidoscope/common/symbol_ids.hpp>
#include <kaleidoscope/frontend/syntactical_analysis/marshall.hpp>
#include <kaleidoscope/frontend/semantic_analysis/scope.hpp>
//=====================================================================
using namespace atma::sooty;
//=====================================================================

kal::resolve::closeness::Enum kal::resolve::types(atma::sooty::const_parseme_ptr_ref lhs, atma::sooty::const_parseme_ptr_ref rhs, scopeme_ptr_ref S)
{
	switch (lhs->id) {
		// function-types
		case ids::function_call:
		case ids::function: {
			switch (rhs->id) {
				case ids::function_call:
				case ids::function:
					return detail::function_type(lhs, rhs, S);
			}
		}
		
		// default to a direct comparison (works for -most- things)
		default:
		{
			if (marshall::type(lhs)->id == ids::function_call)
			{
				// find function matching it
				parseme_ptr param_func = scope::find_value(S, lhs, resolve::closeness::perfect).front();
				return (marshall::type(rhs)->id == marshall::function::return_type(param_func)->id) ? closeness::perfect : closeness::not_at_all;
			}
			
			return (marshall::type(lhs)->id == marshall::type(rhs)->id) ? closeness::perfect : closeness::not_at_all;
		}
	}
	
	return closeness::not_at_all;
}

kal::resolve::closeness::Enum kal::resolve::detail::function_type(const_parseme_ptr_ref call, const_parseme_ptr_ref candidate, scopeme_ptr_ref S)
{
	ATMA_ASSERT(call->id == ids::function_call || call->id == ids::function);
	ATMA_ASSERT(candidate->id == ids::function_call || candidate->id == ids::function);
	
	parseme_container& call_pl = marshall::parameter_list(call)->children;
	parseme_container& function_pl = marshall::parameter_list(candidate)->children;
	
	if (call_pl.size() != function_pl.size()) return closeness::not_at_all;
	
	closeness::Enum close = closeness::perfect;
	
	parseme_container::const_iterator argument = call_pl.begin();
	parseme_container::const_iterator parameter = function_pl.begin();
	
	for ( ; argument != call_pl.end() && parameter != function_pl.end(); ++argument, ++parameter)
	{
		closeness::Enum c = resolve::types(*argument, *parameter, S);
		
		if (c == closeness::not_at_all) {
			close = c;
			break;
		}
		else if (c == closeness::castable) {
			close = c;
		}
	}
	
	//
	
	return close;
}









bool kal::resolve::equal::function_call_vs_function::operator ()(atma::sooty::const_parseme_ptr_ref candidate) const
{
	ATMA_ASSERT(candidate->id == ids::function_call || candidate->id == ids::function);

	parseme_container& call_pl = marshall::parameter_list(call_)->children;
	parseme_container& candidate_pl = marshall::parameter_list(candidate)->children;

	if (call_pl.size() != candidate_pl.size()) return closeness::not_at_all;

	closeness::Enum close = closeness::perfect;

	parseme_container::const_iterator argument = call_pl.begin();
	parseme_container::const_iterator parameter = candidate_pl.begin();

	for ( ; argument != call_pl.end() && parameter != candidate_pl.end(); ++argument, ++parameter)
	{
		closeness::Enum c = resolve::types(*argument, *parameter, scope_);

		if (c != closeness_) {
			close = c;
			break;
		}
		else if (c == closeness::castable) {
			close = c;
		}
	}
	
	return close >= closeness_;
}


void kal::resolve::remove_nonmatching_functions(
	atma::sooty::parseme_container& possibilities,
	atma::sooty::const_parseme_ptr_ref call,
	closeness::Enum desired_closeness)
{
	possibilities.erase(std::remove_if(
		possibilities.begin(),
		possibilities.end(),
		std::not1(resolve::equal::function_call_vs_function(call, local_S))
		), possibilities.end());
}

//parseme_container kal::






*/